package com.sky.loveshop.api;

import cn.hutool.extra.spring.SpringUtil;
import com.sky.loveshop.config.CustomFeignInterceptor;
import com.sky.loveshop.entity.common.ApiConstants;
import com.sky.loveshop.utils.FeignUtil;

/**
 * @author xcy
 * @version V1.0
 * @description 使用feign调用第三方接口
 * @date 2024/9/11 22:07
 */
public interface Apis {

    //------------------------------------------外送帮拉取美团订单
    //MeiTuanApi WAI_SONG_BANG_API = getFeignApi(MeiTuanApi.class, SpringUtil.getProperty(ApiConstants.WAI_SONG_BANG_DOMAIN)); // 不适用拦截器的简陋调用
    //MeiTuanApi WAI_SONG_BANG_API = getFeignApi(MeiTuanApi.class, SpringUtil.getProperty(ApiConstants.WAI_SONG_BANG_DOMAIN), new CustomFeignInterceptor()); // 直接new一个拦截器来使用
    MeiTuanApi WAI_SONG_BANG_API = getFeignApi(MeiTuanApi.class, SpringUtil.getProperty(ApiConstants.WAI_SONG_BANG_DOMAIN), SpringUtil.getBean("customFeignInterceptor")); // 使用bean注入从spring容器中获取拦截器方式调用

    //------------------------------------------收钱吧
    //CollectMoneyApi SHOU_QIAN_BA_API = getFeignApi(CollectMoneyApi.class, SpringUtil.getProperty(ApiConstants.SHOU_QIAN_BA_DOMAIN));
    CollectMoneyApi SHOU_QIAN_BA_API = getFeignApi(CollectMoneyApi.class, SpringUtil.getProperty(ApiConstants.SHOU_QIAN_BA_DOMAIN), SpringUtil.getBean("customFeignInterceptor"));


    //------------------------------------------企业微信机器人发送消息
    QiYeWeChatApi QI_YE_WE_CHAT_API = getFeignApi(QiYeWeChatApi.class, SpringUtil.getProperty(ApiConstants.QI_YE_WE_CHAT_DOMAIN), SpringUtil.getBean("customFeignInterceptor"));


    /**
     * 获取feignClient(不带拦截器)
     */
    static <T> T getFeignApi(Class<T> clazz, String url) {
        return FeignUtil.getDefaultFeignClient(clazz, url);
    }

    /**
     * 获取feignClient(带拦截器) 拦截器能对出入参进行增强处理
     */
    static <T> T getFeignApi(Class<T> clazz, String url, CustomFeignInterceptor customFeignInterceptor) {
        return FeignUtil.getDefaultFeignClient(clazz, url, customFeignInterceptor);
    }

}

/*
    在选择使用Spring容器管理的拦截器（即通过SpringUtil.getBean("customFeignInterceptor")获取的拦截器）还是直接新建一个拦截器（通过new CustomFeignInterceptor()）时，主要考虑以下几个方面：
    1. 性能：
    直接创建（new CustomFeignInterceptor()）：每次调用时都会创建一个新的拦截器实例。如果该拦截器是轻量级的，对性能的影响微乎其微，但如果拦截器内部有相对较重的初始化或状态维护，可能会对性能产生影响。
    Spring管理（getBean方式）：Spring会在容器启动时创建拦截器实例，并在需要时注入。这消除了每次调用时创建新实例的开销，尤其在拦截器持有一些资源（如连接池、配置等）时，这种方式可以更有效率。
    2. 生命周期管理：
    Spring管理：使用Spring的@Service或@Component注解，你可以利用Spring的生命周期管理，包括依赖注入、单例管理等。这意味着如果拦截器中有需要共享的状态或依赖，它们可以通过Spring的依赖注入机制来管理。
    直接创建：如果你新建的拦截器中包含需要管理的状态（例如计数器、配置等），每次调用时都创建新的实例可能导致状态不一致或资源浪费。
    3. 代码整洁性：
    Spring管理：通过容器管理拦截器，你可以使得代码更简洁。依赖于Spring的注入方式，减少了手动管理对象的复杂性。
    直接创建：在复杂项目中，手动创建实例可能导致维护困难，特别是当依赖变多时。
    4. 可测试性：
    Spring管理：使用Spring会让单元测试时更容易模拟和替换依赖，因为Spring会处理这些依赖的生命周期。
    直接创建：手动创建拦截器可能在测试时需要更多的协调和管理，尤其是在多个拦截器和依赖的场景中。
    综合建议
    对于性能： 若拦截器是轻量的且没有状态，性能影响较小，直接创建也可以。但若拦截器较复杂，建议使用Spring管理的方式。
    对于可维护性与可测试性： 推荐使用Spring管理的拦截器方式，它提供了更好的生命周期管理和依赖注入支持，从长远来看更有优势。
    因此，综合考虑，使用Spring容器中的拦截器通常是更推荐的做法，特别是对于更复杂或状态化的拦截器。
 */
